package com.authine.cloudpivot.ext.controller.plan;

import cn.hutool.core.lang.Assert;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author fengjie
 * @version 1.0.0
 * @ClassName WorkRelatedFilesController
 * @Description 工作相关档案
 * @createTime 2023/2/2 8:43
 */
@RestController
@RequestMapping("/public/workRelatedFiles")
@Slf4j
public class WorkRelatedFilesController extends BaseController {
    @Autowired
    CloudSqlService sqlService;

    /**
     * 相关档案审批完成后，数据同步后工作相关档案记录
     */
    @RequestMapping("finish")
    public void finish(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.WORK_RELATED_FILES, bizId);

        //相关档案明细表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.WORK_RELATED_FILES_DETAIL);

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        for (Map<String, Object> map : list) {
            try {
                //将子表中数据处理，随后更新至【工作相关档案记录】
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);

                //判断是否已存在
                String id = existsBizObject(data);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }
                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.WORK_RELATED_FILES_RECORD, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("工作相关档案记录数据新增成功");

                //调用存储过程
                callProcess(id);
            } catch (Exception e) {
                log.info("工作相关档案记录数据维护失败，报错信息：{}", e.getMessage());
                log.info("工作相关档案记录操作失败 company={},archives={},relatedFileFID={}", map.get("company"), map.get("archives"), map.get("relatedFileFID"));
            }
        }
    }

    /**
     * 修改qeo
     */
    @RequestMapping("updateQEO")
    public void updateQEO(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.QEO, bizId);

        //相关档案明细表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.QEO_DETAIL);

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        String tableName = this.getBizObjectFacade().getTableName(CustomSchemaCode.WORK_RELATED_FILES_RECORD);

        for (Map<String, Object> map : list) {
            try {
                //修改QEO数据
                String companyNumber = MapUtils.getString(map, "companyNumber", "");
                String archivesFNumber = MapUtils.getString(map, "archivesFNumber", "");

                StringBuilder sql = new StringBuilder();
                String fileQ = MapUtils.getString(map, "fileQ", "");
                String fileE = MapUtils.getString(map, "fileE", "");
                String fileO = MapUtils.getString(map, "fileO", "");
                sql.append("update ").append(tableName)
                        .append(" set fileQ = '").append(fileQ).append("'")
                        .append(",fileE = '").append(fileE).append("'")
                        .append(",fileO = '").append(fileO).append("'")
                        .append(",auditDate = '").append(now).append("'")
                        .append(",approval = '").append(approval).append("'")
                        .append(" where companyNumber = '").append(companyNumber).append("'")
                        .append(" and archivesFNumber = '").append(archivesFNumber).append("'");
                sqlService.update(sql.toString());
                log.info("工作相关档案记录数据修改成功");

                //调用存储过程
                callUpdateProcess(companyNumber, archivesFNumber);
            } catch (Exception e) {
                log.info("工作相关档案记录数据维护失败，报错信息：{}", e.getMessage());
                log.info("工作相关档案记录操作失败 company={},archives={},relatedFileFID={}", map.get("company"), map.get("archives"), map.get("relatedFileFID"));
            }
        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.VOID_WORK_RELATED_FILES, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.VOID_WORK_RELATED_FILES_DETAIL);

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        //获取审批人
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);

        for (Map<String, Object> map : list) {
            try {
                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //判断是否已存在
                String id = existsBizObject(data);
                if (StringUtils.isEmpty(id)) {
                    //判断是否已存在，如果不存在，放弃这条数据，直接跳过此次循环
                    continue;
                } else if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.WORK_RELATED_FILES_RECORD, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("工作相关档案记录作废操作成功");
                //调用存储过程
                callProcessToVoid(id);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                log.info("工作相关档案记录操作失败 company={},archives={},relatedFileFID={}", map.get("company"), map.get("archives"), map.get("relatedFileFID"));
            }
        }
    }


    /**
     * 调用存储过程
     * ------相关档案
     * exec   SyncRelevantFiles
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.WORK_RELATED_FILES_RECORD);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String company = MapUtils.getString(map, "company", "");//公司fid
        String archives = MapUtils.getString(map, "archives", "");//档案FID
        String relatedFileFID = MapUtils.getString(map, "relatedFileFID", "");//相关档案FID
        String approval = MapUtils.getString(map, "approval", "");//审批人


        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncRelevantFiles '%s','%s','%s','%s'",
                company, archives, relatedFileFID, approval);

        log.info("\n==========准备调用存储过程:{}", execSql);

        sqlService.execute(CloudSqlService.htEas, execSql);

        log.info("\n=============存储过程执行完成");

    }

    /**
     * 调用存储过程
     * ------相关档案QEO
     * exec   SyncRelevantQEO
     */
    private void callUpdateProcess(String companyNumber, String archivesFNumber) {
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.WORK_RELATED_FILES_RECORD);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where companyNumber ='").append(companyNumber).append("'")
                .append(" and archivesFNumber ='").append(archivesFNumber).append("'").append(";");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String company = MapUtils.getString(map, "company", "");//公司fid

        String fileQ = MapUtils.getString(map, "fileQ", "");//相关档案FID
        Integer fileQValue = "√".equals(fileQ) ? 1 : 0;
        String fileE = MapUtils.getString(map, "fileE", "");//审批人
        Integer fileEValue = "√".equals(fileE) ? 1 : 0;
        String fileO = MapUtils.getString(map, "fileO", "");//审批人
        Integer fileOValue = "√".equals(fileO) ? 1 : 0;

        String approval = MapUtils.getString(map, "approval", "");//审批人


        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncRelevantQEO '%s','%s','%s','%s','%s','%s'",
                company, archivesFNumber, fileQValue, fileEValue, fileOValue, approval);

        log.info("\n==========准备调用存储过程:{}", execSql);

        sqlService.execute(CloudSqlService.htEas, execSql);

        log.info("\n=============存储过程执行完成");

    }

    /**
     * 调用作废存储过程
     * --------相关档案 作废
     * exec    RelevantDisable
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.WORK_RELATED_FILES_RECORD);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        //调用存储过程
        String company = MapUtils.getString(map, "company", "");//公司fid
        String archivesFNumber = MapUtils.getString(map, "archivesFNumber", "");//档案代码
        String relatedFileCode = MapUtils.getString(map, "relatedFileCode", "");//相关档案代码


        String execSql = String.format("exec [HG_LINK].[hg].[dbo].RelevantDisable  '%s','%s','%s'",
                company, archivesFNumber, relatedFileCode);

        log.info("\n==========准备调用[RelevantDisable]作废存储过程:{}", execSql);

        sqlService.execute(CloudSqlService.htEas, execSql);

        log.info("\n=============作废存储过程[RelevantDisable]执行完成");

    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity17";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            final String finalActivityCode2 = "Activity3";
            Optional<WorkItemModel> second = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode2)).findFirst();
            if (second.isPresent()) {
                WorkItemModel workItemModel = second.get();
                participant = workItemModel.getParticipant();
            }
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.WORK_RELATED_FILES_RECORD);
//        // 公司
//        Map<String,Object> companyMap = (Map<String, Object>) data.get("company");
//        // 代码
//        Map<String,Object> archivesMap = (Map<String, Object>) data.get("archives");
//        //相关档案代码
//        Map<String,Object> relatedFileFIDMap = (Map<String, Object>) data.get("relatedFileFID");

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName)
                .append(" where company='").append(data.get("company")).append("'")
                .append(" and archives='").append(data.get("archives")).append("'")
                .append(" and relatedFileFID='").append(data.get("relatedFileFID")).append("'")
                .append(";");
        Map<String, Object> map = sqlService.getMap(sql.toString());
        return (String) map.get("id");
    }

    /**
     * 转换成  基础表-总公司档案 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String auditer) {
        Map<String, Object> data = new HashMap<>();
        List<String> keys = Arrays.asList("companyNumber", "archivesFNumber", "fileName", "remarks", "workDesc", "filesMainDeptNumber", "filesMainDeptName", "filesMainPositionNumber",
                "filesMainPositionName", "relatedFileCode", "relevantFileName", "relevantFileRemarks", "relatedFileDescription", "relevantFilesMainDeptNumber",
                "relevFilesMainPositionNumber");
        // 子表id
        data.put("childTableID", map.get("id"));
        keys.forEach(key -> data.put(key, map.get(key)));

        // 公司
        Map<String, Object> companyMap = (Map<String, Object>) map.get("company");
        data.put("company", companyMap.get("id"));
        // 代码
        Map<String, Object> archivesMap = (Map<String, Object>) map.get("archives");
        data.put("archives", archivesMap.get("id"));
        //相关档案代码
        Map<String, Object> relatedFileFIDMap = (Map<String, Object>) map.get("relatedFileFID");
        data.put("relatedFileFID", relatedFileFIDMap.get("id"));
        //档案职能
        Map<String, Object> functionMap = (Map<String, Object>) map.get("function");
        data.put("function", functionMap.get("id"));
        //相关档案职能
        Map<String, Object> relevantFunctionMap = (Map<String, Object>) map.get("relevantFunction");
        data.put("relevantFunction", relevantFunctionMap.get("id"));
        //档案类型
        Map<String, Object> fileTypeMap = (Map<String, Object>) map.get("fileType");
        data.put("fileType", fileTypeMap.get("id"));
        //相关档案类型
        Map<String, Object> relatedFileTypeMap = (Map<String, Object>) map.get("relatedFileType");
        data.put("relatedFileType", relatedFileTypeMap.get("id"));
        //审批时间和审批人
        data.put("auditDate", auditDate);
        data.put("approval", auditer);
        return data;
    }
}
